package msigraphx.gibbsSampler;

import java.util.List;
import java.util.Random;
import java.util.Vector;

public class GibbsSampler<Type> {
	private int samplesNum;
	private List<CondDistr<Type>> distrsList;
	private List<RandomVariable<Type>> randVarList;
	
	public GibbsSampler(int samplesNum, List<RandomVariable<Type>> randVarList, List<CondDistr<Type>> condDistrList) {
		this.samplesNum = samplesNum;
		this.randVarList = randVarList;
		this.distrsList = condDistrList;
	}
	
	@SuppressWarnings("unchecked")
	public List<Sample<Type>> compute() {
		List<Sample<Type>> samples = new Vector<Sample<Type>>();
		Random rand = new Random();
		Sample<Type> actualSample = new Sample<Type>();
		actualSample.initRand(randVarList);
		int varIndex;
		CondDistr<Type> distr;
		List<RandomVariableValue<Type>> otherVariables;
		VarDistr<Type> varDistr;
		RandomVariableValue<Type> newVarValue;
		
		for(int k=0; k<samplesNum; ++k) {
			varIndex = rand.nextInt(randVarList.size());
			distr = distrsList.get(varIndex);
			otherVariables = actualSample.getWithoutVar(varIndex);
			varDistr = distr.getDistrByAllDependantVar(otherVariables);
			newVarValue = varDistr.drawUniformlyFromDistr();
			actualSample.replaceVarVal(varIndex, newVarValue);
			samples.add((Sample<Type>)actualSample.clone());
		}
		
		return samples;
	}
}
